
package com.tceasy.gateway.util;

import com.tceasy.util.GzipUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class RSA{

    static final Logger logger= LoggerFactory.getLogger(RSA.class);

	public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
	
	/**
	* RSA签名
	* @param content 待签名数据
	* @param privateKey 商户私钥
	* @param input_charset 编码格式
	* @return 签名值
	*/
	public static String sign(String content, String privateKey, String input_charset)
	{
        try 
        {
        	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); 
        	KeyFactory keyf 				= KeyFactory.getInstance("RSA");
        	PrivateKey priKey 				= keyf.generatePrivate(priPKCS8);

            java.security.Signature signature = java.security.Signature
                .getInstance(SIGN_ALGORITHMS);

            signature.initSign(priKey);
            signature.update( content.getBytes(input_charset) );

            byte[] signed = signature.sign();
            
            return Base64.encode(signed);
        }
        catch (Exception e) 
        {
        	logger.error(e.toString());
        }
        
        return null;
    }
	
	/**
	* RSA验签名检查
	* @param content 待签名数据
	* @param sign 签名值
	* @param ali_public_key 支付宝公钥
	* @param input_charset 编码格式
	* @return 布尔值
	*/
	public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
	{
		try 
		{
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	        byte[] encodedKey = Base64.decode(ali_public_key);
	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

		
			java.security.Signature signature = java.security.Signature
			.getInstance(SIGN_ALGORITHMS);
		
			signature.initVerify(pubKey);
			signature.update( content.getBytes(input_charset) );
		
			boolean bverify = signature.verify( Base64.decode(sign) );
			return bverify;
			
		} 
		catch (Exception e) 
		{
            logger.error(e.toString());
		}
		
		return false;
	}
	
	/**
	* 解密
	* @param content 密文
	* @param private_key 商户私钥
	* @param input_charset 编码格式
	* @return 解密后的字符串
	*/
	public static String decrypt(String content, String private_key, String input_charset) throws Exception {
        PrivateKey prikey = getPrivateKey(private_key);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, prikey);

        InputStream ins = new ByteArrayInputStream(Base64.decode(content));
        ByteArrayOutputStream writer = new ByteArrayOutputStream();
        //rsa解密的字节大小最多是128，将需要解密的内容，按128位拆开解密
        byte[] buf = new byte[128];
        int bufl;

        while ((bufl = ins.read(buf)) != -1) {
            byte[] block = null;

            if (buf.length == bufl) {
                block = buf;
            } else {
                block = new byte[bufl];
                for (int i = 0; i < bufl; i++) {
                    block[i] = buf[i];
                }
            }

            writer.write(cipher.doFinal(block));
        }

        return new String(writer.toByteArray(), input_charset);
    }

    /**
     *加密的方法
     */
    public  static String encrypt(String source,String publicKey) throws Exception{
        PublicKey  key = getPublicKey(publicKey);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,key);
        byte[] sbt = source.getBytes();
        byte [] epByte = cipher.doFinal(sbt);
        String epStr =  Base64.encode(epByte);
        return epStr;
    }


    public static void main(String[] args) throws Exception {
        String content="originalData\t\"<tns:batch-settlement-apply-request xmlns:ns0=\"http://www.99bill.com/schema/commons\" xmlns:ns1=\"http://www.99bill.com/schema/fo/commons\" xmlns:tns=\"http://www.99bill.com/schema/fo/settlement\">\\n  <tns:request-header>\\n    <tns:version xmlns:tns=\"http://www.99bill.com/schema/fo/commons\">\\n      <ns0:version>1.0.1</ns0:version>\\n      <ns0:service>fo.batch.settlement.pay</ns0:service>\\n    </tns:version>\\n    <ns1:time>20151016173528</ns1:time>\\n  </tns:request-header>\\n  <tns:request-body>\\n    <tns:payer-acctCode>1001213884001</tns:payer-acctCode>\\n    <tns:batch-no>batchNo_20151016173528</tns:batch-no>\\n    <tns:apply-date>20151016173528</tns:apply-date>\\n    <tns:name>学升测试</tns:name>\\n    <tns:total-amt>10000</tns:total-amt>\\n    <tns:total-cnt>2</tns:total-cnt>\\n    <tns:fee-type>0</tns:fee-type>\\n    <tns:cur>RMB</tns:cur>\\n    <tns:checkAmt-cnt>0</tns:checkAmt-cnt>\\n    <tns:batch-fail>0</tns:batch-fail>\\n    <tns:recharge-type>1</tns:recharge-type>\\n    <tns:auto-refund>0</tns:auto-refund>\\n    <tns:phoneNote-flag>0</tns:phoneNote-flag>\\n    <tns:merchant-memo1>memo1</tns:merchant-memo1>\\n    <tns:merchant-memo2>memo2</tns:merchant-memo2>\\n    <tns:merchant-memo3>memo3</tns:merchant-memo3>\\n    <tns:pay2bank-list>\\n      <tns:pay2bank>\\n        <ns1:merchant-id>orderid_201510161735280</ns1:merchant-id>\\n        <ns1:amt>5000</ns1:amt>\\n        <ns1:bank>中国工商银行</ns1:bank>\\n        <ns1:name>丹丹测试</ns1:name>\\n        <ns1:bank-card-no>6225881258771673</ns1:bank-card-no>\\n        <ns1:branch-bank>上海支行</ns1:branch-bank>\\n        <ns1:payee-type>0</ns1:payee-type>\\n        <ns1:province>江苏/jsnj</ns1:province>\\n        <ns1:city>南京/jsnj</ns1:city>\\n        <ns1:memo>快钱备注</ns1:memo>\\n        <ns1:bank-purpose>银行交易备注</ns1:bank-purpose>\\n        <ns1:bank-memo>学升</ns1:bank-memo>\\n        <ns1:payee-note>通知内容</ns1:payee-note>\\n        <ns1:payee-mobile>15850693123</ns1:payee-mobile>\\n        <ns1:payee-email>624728369@qq.com</ns1:payee-email>\\n        <ns1:period/>\\n        <ns1:merchant-memo1>order1</ns1:merchant-memo1>\\n        <ns1:merchant-memo2>order2</ns1:merchant-memo2>\\n        <ns1:merchant-memo3>order3</ns1:merchant-memo3>\\n      </tns:pay2bank>\\n      <tns:pay2bank>\\n        <ns1:merchant-id>orderid_201510161735281</ns1:merchant-id>\\n        <ns1:amt>5000</ns1:amt>\\n        <ns1:bank>中国工商银行</ns1:bank>\\n        <ns1:name>丹丹测试</ns1:name>\\n        <ns1:bank-card-no>6225881258771673</ns1:bank-card-no>\\n        <ns1:branch-bank>上海支行</ns1:branch-bank>\\n        <ns1:payee-type>0</ns1:payee-type>\\n        <ns1:province>江苏/jsnj</ns1:province>\\n        <ns1:city>南京/jsnj</ns1:city>\\n        <ns1:memo>快钱备注</ns1:memo>\\n        <ns1:bank-purpose>银行交易备注</ns1:bank-purpose>\\n        <ns1:bank-memo>学升</ns1:bank-memo>\\n        <ns1:payee-note>通知内容</ns1:payee-note>\\n        <ns1:payee-mobile>15850693123</ns1:payee-mobile>\\n        <ns1:payee-email>624728369@qq.com</ns1:payee-email>\\n        <ns1:period/>\\n        <ns1:merchant-memo1>order1</ns1:merchant-memo1>\\n        <ns1:merchant-memo2>order2</ns1:merchant-memo2>\\n        <ns1:merchant-memo3>order3</ns1:merchant-memo3>\\n      </tns:pay2bank>\\n    </tns:pay2bank-list>\\n  </tns:request-body>\\n</tns:batch-settlement-apply-request>\" (id=55)\t\n";
        byte[] orc = GzipUtil.gzip(content.getBytes("utf-8"));
        String publickey="MIIEVzCCAz+gAwIBAgIJAMyX6hgX0bZ3MA0GCSqGSIb3DQEBBQUAMHoxCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJTSDELMAkGA1UEBxMCU0gxDzANBgNVBAoTBjk5YmlsbDEMMAoGA1UECxMDUE9BMQwwCgYDVQQDEwNJTkYxJDAiBgkqhkiG9w0BCQEWFXBvYV9lYV9pbmZAOTliaWxsLmNvbTAeFw0xNDA2MzAwMjMxMzBaFw0zNDA2MzAwMjMxMzBaMHoxCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJTSDELMAkGA1UEBxMCU0gxDzANBgNVBAoTBjk5YmlsbDEMMAoGA1UECxMDUE9BMQwwCgYDVQQDEwNJTkYxJDAiBgkqhkiG9w0BCQEWFXBvYV9lYV9pbmZAOTliaWxsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdZsacD41SXYXst4dfRR1mOIDKRvPb9G19SDT8TgTYL5CU0x+22Kxu0XhBWQ91iOtXaYF24HOoUnuZIC1DL1ul6WJoEnvGIdn3wXkh+jt6kwhr/EAzBA2a8oBrDXRAXV5tb6AO90kZvz/H3hUW8zx8SEHm7pATuSvXgCSBWU6J2DGNfpcaxkj+G8PhrhfWgmy0J18+HbO9ugt9i4wV9S7VDKqgrcCb3K7VRZRiLpa5KvB+b+fHe4M15ODCSSD4wFPFxxWX1x4Ih8I25Bgrmx3tskWStYNbPDH4JW6ZpA19wfFtqA7eO12GuuQWdEGCtQSqxvgdKGoG1T02DdMWdlekCAwEAAaOB3zCB3DAdBgNVHQ4EFgQUr+b69rLVT8kUz5mOAtFXH2vqc1swgawGA1UdIwSBpDCBoYAUr+b69rLVT8kUz5mOAtFXH2vqc1uhfqR8MHoxCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJTSDELMAkGA1UEBxMCU0gxDzANBgNVBAoTBjk5YmlsbDEMMAoGA1UECxMDUE9BMQwwCgYDVQQDEwNJTkYxJDAiBgkqhkiG9w0BCQEWFXBvYV9lYV9pbmZAOTliaWxsLmNvbYIJAMyX6hgX0bZ3MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHSm2rzEoygqrOMKPypyMWd9LWXa8wvNkzBiQyuPbaIjx4BNZd8ImlaOCXgk5Z5JDja1jPyYSac+G3tzk4e/9wUgRY8rxnKhr7NCPKdbWZGC5O27LM/mCM9wj+cWIvi1DKSD3oe/tkN26mbtcHpug8Ubzz9hABc7f07lZEe8tgV8bxvrLHzmFrEoBRerAKqMyGEb+a57RLa/Lv8/OhqRlYzERy6N32egpSCQVtWLMyQI861N/QqyKW3egwUsPLk5c6/qVsz2a4Ka5SUtsLYUS/tfo4zIitfXxDGqG0oYlFcthVu6iy6Pju5q5l/XDGnjTVHiiVmo1WeSU3Ps23gEhFM=";
        String result=RSA.encrypt("",publickey);
        System.out.println(result);
    }

	/**
	* 得到私钥
	* @param key 密钥字符串（经过base64编码）
	* @throws Exception
	*/
	public static PrivateKey getPrivateKey(String key) throws Exception {

		byte[] keyBytes= Base64.decode(key);
		
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		
		return privateKey;
	}

    /**
     * 得到公钥
     * @param key 密钥字符串（经过base64编码）
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes= Base64.decode(key);
        X509EncodedKeySpec x509ek = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509ek);
        return publicKey;
    }
}
